#include "gtest/gtest.h"

TEST(AssertionTest, FloatAssertion) {
    ASSERT_NEAR(52.1899, 52.1898, 0.1);
}

// Returns true if m and n have no common divisors except 1.
bool MutuallyPrime(int m, int n) {
    auto smaller = m < n ? m : n;
    for (auto i = 2; i < smaller; i++) {
        if (m % i == 0 && n % i == 0) {
            return false;
        }
    }
    return true;
}

// Returns the smallest prime common divisor of m and n,
// or 1 when m and n are mutually prime.
int SmallestPrimeCommonDivisor(int m, int n) {
    auto smaller = m < n ? m : n;
    for (auto i = 2; i < smaller; i++) {
        if (m % i == 0 && n % i == 0) {
            return i;
        }
    }
    return 1;
}

TEST(AssertionTest, PredicateAssertion) {
    const int a = 3;
    const int b = 4;
    const int c = 10;
    EXPECT_PRED2(MutuallyPrime, a, b);  // Succeeds
    EXPECT_PRED2(MutuallyPrime, b, c);  // Fails
}


// A predicate-formatter for asserting that two integers are mutually prime.
testing::AssertionResult AssertMutuallyPrime(const char* m_expr,
                                             const char* n_expr,
                                             int m,
                                             int n) {
    if (MutuallyPrime(m, n)) return testing::AssertionSuccess();
    return testing::AssertionFailure() << m_expr << " and " << n_expr
                                       << " (" << m << " and " << n << ") are not mutually prime, "
                                       << "as they have a common divisor " << SmallestPrimeCommonDivisor(m, n);
}

TEST(AssertionTest, PredicateFormatAssertion) {
    const int a = 3;
    const int b = 4;
    const int c = 10;
    EXPECT_PRED_FORMAT2(AssertMutuallyPrime, a, b);  // Succeeds
    EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c);  // Fails
}

TEST(AssertionTest, PredicateFloatAssertion) {
    EXPECT_PRED_FORMAT2(::testing::FloatLE, 3.1998, 3.1999);  // Succeeds
}

